import tkinter as tk
from tkinter import messagebox
from datetime import datetime, timedelta
import zlib  # 用于CRC校验
import string

def calculate_crc(data):
    """计算数据的CRC32校验值（返回4位数字）"""

    crc_value = zlib.crc32(data.encode()) & 0xFFFFFFFF
    
    return f"{crc_value % 10000:04d}"  # 取最后4位数字

def str_to_digits(input_str):
    """将字母数字字符串转换为纯数字表示"""
    digits = []
    for c in input_str:
        if c.isdigit():
            digits.append(c)
        else:
            # 将字母转换为数字 (A=0, B=1,..., Z=25)
            digit = str(ord(c.upper()) - ord('A'))
            digits.append(digit)
    return ''.join(digits)

def generate_registration_code():
    device_id = entry_id.get().strip()
    
    # 验证设备ID长度
    if len(device_id) == 0:
        messagebox.showerror("错误", "设备ID不能为空")
        return
    
    # 获取选择的期限
    selected_period = period_var.get()
    
    # 计算到期日期
    today = datetime.now()
    if selected_period == "7天":
        expiry_date = today + timedelta(days=7)
    elif selected_period == "10天":
        expiry_date = today + timedelta(days=10)
    elif selected_period == "一个月":
        expiry_date = today + timedelta(days=30)  # 简化为30天
    elif selected_period == "永久":
        expiry_date = datetime(1999, 12, 31)  # 永久使用
    else:
        messagebox.showerror("错误", "请选择有效期限")
        return
    
    # 格式化日期为YYMMDD
    expiry_str = expiry_date.strftime("%y%m%d")
    
    # 将设备ID转换为数字表示
    device_digits = str_to_digits(device_id)
    
    # 生成校验数据
    data_to_hash = f"{device_digits}{expiry_str}"
    
    # 计算CRC校验码
    crc_code = calculate_crc(data_to_hash)
    
    # 组合注册码 (6位日期 + 4位CRC)
    registration_code = expiry_str + crc_code
    
    # 确保总长度为10位数字
    registration_code = registration_code[:10].ljust(10, '0')
    
    # 显示生成的注册码
    entry_code.delete(0, tk.END)
    entry_code.insert(0, registration_code)

def verify_registration_code():
    device_id = entry_id.get().strip()
    registration_code = entry_code.get().strip()
    
    if not device_id or not registration_code:
        messagebox.showerror("错误", "请输入设备ID和注册码")
        return
    
    if len(registration_code) != 10 or not registration_code.isdigit():
        messagebox.showerror("错误", "注册码必须是10位数字")
        return
    
    try:
        # 解析注册码
        expiry_str = registration_code[:6]  # 前6位是日期
        crc_received = registration_code[6:]  # 后4位是CRC
        
        # 将设备ID转换为数字表示
        device_digits = str_to_digits(device_id)
        
        # 重新计算CRC
        data_to_hash = f"{device_digits}{expiry_str}"
        crc_calculated = calculate_crc(data_to_hash)
        
        # 验证CRC
        if crc_received != crc_calculated:
            messagebox.showerror("验证失败", "注册码校验失败")
            return
        
        # 解析日期
        expiry_date = datetime.strptime(expiry_str, "%y%m%d")
        
        # 检查是否过期
        if expiry_date < datetime.now() and expiry_date.year != 1999:
            messagebox.showerror("验证结果", f"注册码已过期 (到期日: {expiry_date.strftime('%Y-%m-%d')}")
        else:
            if expiry_date.year == 1999:
                messagebox.showinfo("验证结果", "注册码有效 (永久)")
            else:
                messagebox.showinfo("验证结果", f"注册码有效 (到期日: {expiry_date.strftime('%Y-%m-%d')})")
                
    except Exception as e:
        messagebox.showerror("错误", f"注册码验证失败: {str(e)}")

def create_exe():
    # 创建主窗口
    root = tk.Tk()
    root.title("设备注册码生成器")
    root.geometry("400x300")
    
    # 设备ID输入
    global entry_id
    tk.Label(root, text="设备ID (字母数字组合):").pack(pady=(10, 0))
    entry_id = tk.Entry(root, width=20)
    entry_id.pack()
    
    # 期限选择
    global period_var
    period_var = tk.StringVar(value="7天")
    
    tk.Label(root, text="选择期限:").pack(pady=(10, 0))
    
    frame_period = tk.Frame(root)
    frame_period.pack()
    
    periods = ["7天", "10天", "一个月", "永久"]
    for period in periods:
        rb = tk.Radiobutton(frame_period, text=period, variable=period_var, value=period)
        rb.pack(side=tk.LEFT, padx=5)
    
    # 生成按钮
    btn_generate = tk.Button(root, text="生成注册码", command=generate_registration_code)
    btn_generate.pack(pady=10)
    
    # 注册码显示
    global entry_code
    tk.Label(root, text="注册码 (10位数字):").pack()
    entry_code = tk.Entry(root, width=20)
    entry_code.pack()
    
    # 验证按钮
    btn_verify = tk.Button(root, text="验证注册码", command=verify_registration_code)
    btn_verify.pack(pady=10)
    
    # 退出按钮
    btn_exit = tk.Button(root, text="退出", command=root.quit)
    btn_exit.pack(pady=5)
    
    root.mainloop()

if __name__ == "__main__":
    create_exe()